package com.jeffpalm.pandoralastfm;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;


abstract class App {

  protected final static String PROP_USERNAME = "username";
  protected final static String PROP_USE_LAST_FM = "useLastFm";

  private final Properties props;
  private final PandoraLastFmBridge bridge;

  App() {
    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
      public void run() {
        saveProperties();
      }
    }));
    props = loadProperties();
    bridge = new PandoraLastFmBridge(getUsername());
  }

  protected final void save(String userName, boolean lastFmIsSelected) {
    setProperty(PROP_USERNAME, userName);
    setBooleanProperty(PROP_USE_LAST_FM, lastFmIsSelected);
  }

  protected final Pandora pandora() {
    return getBridge().getPandora();
  }

  protected final LastFm lastfm() {
    return getBridge().getLastFm();
  }

  protected final File getPropsFile() {
    return new File(System.getProperty("user.home"), "." + getClass().getSimpleName());
  }

  protected final void handle(Throwable e) {
    handle(e, null);
  }

  protected final void handle(Throwable e, String msg) {
    e.printStackTrace();
    if (msg != null) System.err.println(msg);
  }
  
  protected final String getStatusString() {
    StringBuffer sb = new StringBuffer();
    
    sb.append("Artist : ");
    sb.append(bridge.getPandora().getCurrentArtist());
    sb.append("\n");
    
    sb.append("Album  : ");
    sb.append(bridge.getPandora().getCurrentAlbum());
    sb.append("\n");
    
    sb.append("Track  : ");
    sb.append(bridge.getPandora().getCurrentTrack());
    sb.append("\n");
    
    return sb.toString();
  }

  // --------------------------------------------------
  // Properties
  // --------------------------------------------------

  protected final String getProperty(String key) {
    return props.getProperty(key);
  }

  protected final String getProperty(String key, String defaultValue) {
    return props.getProperty(key, defaultValue);
  }

  protected final boolean getBooleanProperty(String key) {
    String val = getProperty(key, "");
    return !(val.equals("") || val.toLowerCase().equals("false"));
  }

  protected final String setProperty(String key, String val) {
    Object o = props.setProperty(key, val);
    return o == null ? null : String.valueOf(o);
  }

  protected final boolean setBooleanProperty(String key, boolean val) {
    setProperty(key, String.valueOf(val));
    return val;
  }

  // -----------------------------------------------------
  // Private
  // -----------------------------------------------------

  protected String getUsername() {
    return getProperty(PROP_USERNAME);
  }

  private Properties loadProperties() {
    Properties props = new Properties();
    File propsFile = getPropsFile();
    if (propsFile.exists()) {
      try {
        props.load(new FileInputStream(propsFile));
      } catch (IOException e) {
        handle(e);
      }
    }
    return props;
  }

  @SuppressWarnings("deprecation")
  private void saveProperties() {
    try {
      props.save(new FileOutputStream(getPropsFile()), getClass().getSimpleName());
    } catch (FileNotFoundException e) {
      handle(e);
    }
  }

  public PandoraLastFmBridge getBridge() {
    return bridge;
  }
  
  protected final void outln(String msg) {
    System.out.println(msg);
  }

  protected final void out(String msg) {
    System.out.print(msg);
    System.out.flush();
  }


}
